package es.xpt.ysf.jaas;

import java.security.Principal;
import java.security.acl.Group;
import java.util.ArrayList;
import java.util.List;

import javax.security.auth.Subject;
import javax.security.jacc.PolicyContext;
import javax.security.jacc.PolicyContextException;
import javax.servlet.http.HttpServletRequest;

import org.jboss.web.tomcat.security.JBossSecurityMgrRealm;

import es.xpt.ysf.logging.LogManager;
import es.xpt.ysf.track.Track;
import es.xpt.ysf.track.TrackInterceptor;
import es.xpt.ysf.track.TrackUtils;
import es.xpt.ysf.view.model.UserBean;
import es.xpt.ysf.web.Constants;

//public class YedraSecurityMgr extends JBossWebRealm {
public class YedraSecurityMgr extends JBossSecurityMgrRealm { // NO_UCD
	public Principal authenticate(String username, String credentials) {

		try {
			HttpServletRequest request = (HttpServletRequest) PolicyContext
					.getContext("javax.servlet.http.HttpServletRequest");
			String application = (String) request.getParameter("application");
			UserBean ub = (UserBean) request.getSession().getAttribute( Constants.USER_INFORMATION.getValue());
			if ( application==null )
				application = ub.getApplication();
			
			Principal p = super.authenticate(username + "@" + application, credentials);

			Subject caller = (Subject) PolicyContext.getContext("javax.security.auth.Subject.container");
			
			if ( caller!=null && caller.getPrincipals()!=null ) {			
				
				ub.setUserCode(username);
				ub.setApplication(application);
				ub.setIpAddress(request.getRemoteAddr());

//				request.getSession().setAttribute(Constants.USER_INFORMATION.getValue(), ub);
				
				YSFPrincipal ref = null;
				Group[] roles = new Group[1];
				for (Principal prin : caller.getPrincipals()) {
					if ((prin instanceof YSFPrincipal)) {
						ref = (YSFPrincipal)prin;
						ub.setEntity(ref.getEntity());
						if ( ref.getCompany()!=null )
							ub.setCompany(ref.getCompany());
						ub.setUserName(ref.getDescription());
						ub.setLocale(ref.getLocale());
						ub.setViewAuthenticated(true);
						ub.setSystem(false);
						ub.setDatasource(ref.getDatasource());
						ub.setBigData(ref.getBigData());
					} else if ( prin instanceof Group ) {
						roles[0] = (Group)prin;
						ub.setRoles(roles);
					}
				}
				ref.setRoles(roles);
				ub.afterLogin();
				trackLogin(ub);
			} else {
				LogManager.getLog(getClass()).info("FAILED LOGIN USER: " + username + " from IP: "  +request.getRemoteAddr());
			}
			
			return p;
		} catch (PolicyContextException e) {
			// Que dios nos pille confesados
			LogManager.getLog(getClass()).error(e.getMessage(), e);

		}
		return null;
	}

	private void trackLogin(UserBean ub) {
		try {
			List<Object> params = new ArrayList<Object>(1);
			params.add(ub.getIpAddress());
			Track newTrack = TrackInterceptor.buildSingleTrack( (List<String>)null, ub.getUserCode(),null, "login", params);
			TrackUtils.track(newTrack);
		} catch (Exception e) {
			LogManager.getLog(getClass()).error("Error while tracking login", e);
		}
	}

}
